package com.kmxd.ams.core.mybatisplus;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.kmxd.ams.core.common.constant.Constants;
import com.kmxd.ams.core.util.DynamicTableNameUtil;
import com.kmxd.ams.core.util.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * mybatis-plus配置类
 *
 * @author admin
 */
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
@Slf4j
public class MybatisPlusConfig {
  @Bean
  public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    // 动态表名设置
    interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor());
    // 数据权限插件
    interceptor.addInnerInterceptor(dataPermissionInterceptor());
    // 分页插件
    interceptor.addInnerInterceptor(paginationInnerInterceptor());
    // 乐观锁插件
    interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
    return interceptor;
  }

  /** 设置动态表名 */
  public DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor() {
    DynamicTableNameInnerInterceptor interceptor = new DynamicTableNameInnerInterceptor();
    interceptor.setTableNameHandler(
        (sql, tableName) -> {
          if (DynamicTableNameUtil.checkTableName(tableName)
              && DynamicTableNameUtil.checkTableName(DynamicTableNameUtil.getTableName())) {
            return StringUtils.isNotBlank(DynamicTableNameUtil.getTableName())
                ? DynamicTableNameUtil.getTableName()
                : tableName;
          }
          // 判断
          if (StrUtil.equals(tableName, Constants.TABLE_NAME_EFILE)
              && StringUtils.isNotBlank(DynamicTableNameUtil.getTableName())
              && DynamicTableNameUtil.getTableName().startsWith(Constants.TABLE_NAME_EFILE + "_")) {
            return StringUtils.isNotBlank(DynamicTableNameUtil.getTableName())
                ? DynamicTableNameUtil.getTableName()
                : tableName;
          }
          // 动态切换电子表名
          if (StrUtil.startWith(tableName, Constants.TABLE_NAME_EFILE)) {
            // 如果是电子文件表开头，并且不等于默认电子文件表则直接使用
            if (DynamicTableNameUtil.checkTableEfile(tableName)) {
              return tableName;
            }
            return ObjectUtil.isNotEmpty(SecurityUtil.getindexNum())
                ? Constants.TABLE_NAME_EFILE + "_" + SecurityUtil.getindexNum()
                : tableName;
          }
          return tableName;
        });
    return interceptor;
  }

  /** 数据权限插件 */
  public DataPermissionInterceptor dataPermissionInterceptor() {
    DataPermissionInterceptor dataPermissionInterceptor = new DataPermissionInterceptor();
    CustomDataPermissionHandler customDataPermissionHandler = new CustomDataPermissionHandler();
    dataPermissionInterceptor.setDataPermissionHandler(customDataPermissionHandler);
    return dataPermissionInterceptor;
  }

  /** 分页插件 */
  public PaginationInnerInterceptor paginationInnerInterceptor() {
    PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
    // 设置数据库类型为mysql
    paginationInnerInterceptor.setDbType(DbType.MYSQL);
    // 设置最大单页限制数量，默认 500 条，-1 不受限制
    paginationInnerInterceptor.setMaxLimit(-1L);
    return paginationInnerInterceptor;
  }

  /** 乐观锁插件 */
  public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() {
    return new OptimisticLockerInnerInterceptor();
  }

  /** 元对象字段填充控制器 */
  @Bean
  public MetaObjectHandler metaObjectHandler() {
    return new CreateAndUpdateMetaObjectHandler();
  }

  /**
   * 自定义 sql注入，扩展自定义方法
   *
   * @return
   */
  @Bean
  public ISqlInjector sqlInjector() {
    return new MySqlInjector();
  }
}
